package org.zezs.sync.mongo.utils;

import com.mongodb.MongoClientURI;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.Socket;
import java.util.List;

/**
 * linux 下隧道开启工具，开始后程序不会自动关闭隧道，ssh命令实现的但是因为密码需要直接传输，客户端请安装  sshpass 工具
 */
public class SSHTunnul {

    static Logger logger = LoggerFactory.getLogger(SSHTunnul.class);

    static String mongoProxy(String url, String sshHost, String sshAcct, String sshPwd, String destHost, int destPort) {
        final String[] result = {url};
        MongoClientURI mongoClientURI = new MongoClientURI(url);
        List<String> hosts = mongoClientURI.getHosts();
        hosts.forEach(s -> {
            System.out.println(s);
            int prot = 27017;
            String host = s;
            if (s.indexOf(":") == -1) {
                host = s.split("[:]")[0].trim();
                prot = Integer.parseInt(s.split("[:]")[1].trim());
            }
            result[0] = result[0].replaceFirst(s, "127.0.0.1" + ":" + prot);
        });
        return result[0];
    }

    public static int open(String sshHost, String sshAcct, String sshPwd, String destHost, int destPort, Integer port) {
        if (checkPortExist(port)) {
            logger.info("端口已经被占用");
        }

//      String cmd = " sshpass -p 密码 ssh -N  -L  :目的host:目的端口 账户@host";
        String cmd = " sshpass -p " + sshPwd + " ssh -N  -L " + port + ":" + destHost + ":" + destPort + " " + sshAcct + "@" + sshHost;
        logger.info("执行代理命令{}", cmd);
        try {
            logger.info("打开代理建立连接");
            Process process = Runtime.getRuntime().exec(cmd);
            Thread.sleep(500L);
            int i = 0;
            while (true) {
                i++;
                if (i > 100) {
                    logger.error("建立代理失败");
                    break;
                }
                if (checkPortExist(port)) {
                    logger.info("建立代理连接成功");
                    return port;
                } else {
                    logger.info("代理建立中");
                    Thread.sleep(500L);
                }

            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    public static boolean checkPortExist(int port) {
        try {
            Socket socket = new Socket("127.0.0.1", port);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}
